AWS再入門2022 AWS Serverless Application Model (AWS SAM)編
こんにちは、リサリサです。
当エントリは弊社コンサルティング部による『AWS 再入門ブログリレー 2022』の 4日目のエントリです。
このブログリレーの企画は、普段 AWS サービスについて最新のネタ・深い/細かいテーマを主に書き連ねてきたメンバーの手によって、 今一度初心に返って、基本的な部分を見つめ直してみよう、解説してみようというコンセプトが含まれています。
AWSをこれから学ぼう!という方にとっては文字通りの入門記事として、またすでにAWSを活用されている方にとってもAWSサービスの再発見や2022年のサービスアップデートのキャッチアップの場となればと考えておりますので、ぜひ最後までお付合い頂ければ幸いです。
では、さっそくいってみましょう。4日目のテーマはAWS Serverless Application Model (AWS SAM)です。
今回のブログでは実際にチュートリアルもを実施しますのでぜひ一度やってみてください!
AWS Serverless Application Model (AWS SAM)とは?
AWS Serverless Application Model (以下AWS SAM) は、AWS で以下のようなサーバーレスアプリケーションを簡単に構築するために使用できるオープンソースのフレームワークです。
AWS CloudFormation の拡張機能になりますので、AWS CloudFormation が分からない方は、下記記事から、先にAWS CloudFormation を理解頂いておくといいと思います。
AWS SAM を使用する利点
AWS SAM でのサーバーレスアプリケーションの作成には以下のような利点があります。
単一のデプロイ構成
AWS SAM を使用すると、関連するコンポーネントやリソースの整理が容易になり、単一のスタック上で操作できるようになります。AWS SAM を使用すると、メモリやタイムアウトなどの設定をリソース間で共有し、単一のバージョン管理されたエンティティとしてすべての関連リソースを一緒にデプロイできます。
AWS CloudFormationの拡張
AWS SAM は AWS CloudFormation の拡張であるため、AWS CloudFormation の信頼性の高いデプロイ機能を利用できます。AWS CloudFormation テンプレートで AWS SAM を使用してリソースを定義できます。また、AWS CloudFormation で利用できるすべてのリソース、組み込み関数、およびその他のテンプレート機能も使用できます。
組み込みのベストプラクティス
AWS SAM を使用して、インフラストラクチャを設定として定義し、デプロイできます。これにより、コードレビューなどのベストプラクティスを使用し、実行できるようになります。
ローカルのデバッグとテスト
Docer をインストールすれば、AWS SAM テンプレートで定義されたサーバーレスアプリケーションのローカルでの構築、テスト、およびデバッグを実行できます。
開発ツールとの緊密な統合
AWS SAM は、サーバーレスアプリケーションを構築するための一連の AWS ツールと併用できます。サーバーレスアプリケーションのデプロイパイプラインを構築するには、CodeBuild、CodeDeploy、および CodePipeline を使用できます。AWS CodeStar を使用して、プロジェクト構造、コードリポジトリ、および自動的に設定される CI/CD パイプラインの使用を開始することもできます。サーバーレスアプリケーションをデプロイするには、Jenkins プラグインを使用できます。Stackery.io ツールキットを使用して、本番用のアプリケーションを構築できます。
AWS SAM の開始方法
IAM 許可と AWS 認証情報を設定する
AWS SAM は CLI で操作するものになるので、ローカル環境に AWS 認証情報の設定が必要になります。認証情報の設定が済んでいる(AWS CLI が使える状態)の方はスキップしてください。
設定がまだの方はAWS 認証情報のセットアップに従って、セットアップを行います。
Docker をインストールする (オプション)
Docker をインストールすると、ローカルでLambdaのテストが出来るようになります。今回はしませんが必要に応じて AWS SAM CLI のインストール の「ステップ 3: Docker をインストールする (オプション)」を参照して、インストールしてください。
AWS SAM CLI をインストールする
今回はUbuntu Server 18.04にインストールしました。他の環境の場合は、 AWS SAM CLI のインストール を参照してください。
$pip install aws-sam-cli $sam --version $SAM CLI, version 1.23.0
チュートリアルをやってみた
チュートリアル: Hello World アプリケーションのデプロイ をやってみました。以下のアプリケーションを作成します。get を叩くと「hello world」が返ってくる API です。
サンプル AWS SAM アプリケーションをダウンロードする
sam init コマンドではサーバーレスアプリケーションを初期化できます。今回は hello-world API のテンプレートをクローンしていきます。
対話式で選択肢が出るので、数字で選んでいきます。
$ sam init Which template source would you like to use? 1 - AWS Quick Start Templates 2 - Custom Template Location Choice: 1 What package type would you like to use? 1 - Zip (artifact is a zip uploaded to S3) 2 - Image (artifact is an image uploaded to an ECR image repository) Package type: 1 Which runtime would you like to use? 1 - nodejs14.x 2 - python3.8 3 - ruby2.7 4 - go1.x 5 - java11 6 - dotnetcore3.1 7 - nodejs12.x 8 - nodejs10.x 9 - python3.7 10 - python3.6 11 - python2.7 12 - ruby2.5 13 - java8.al2 14 - java8 15 - dotnetcore2.1 Runtime: 2 Project name [sam-app]: Cloning app templates from https://github.com/aws/aws-sam-cli-app-templates AWS quick start application templates: 1 - Hello World Example 2 - EventBridge Hello World 3 - EventBridge App from scratch (100+ Event Schemas) 4 - Step Functions Sample App (Stock Trader) 5 - Elastic File System Sample App Template selection: Template selection: Template selection: 1 ----------------------- Generating application: ----------------------- Name: sam-app Runtime: python3.8 Dependency Manager: pip Application Template: hello-world Output Directory: . Next steps can be found in the README file at ./sam-app/README.md SAM CLI update available (1.37.0); (1.23.0 installed) To download: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html
これで、hello-world API のテンプレートがクローンされました。
こんなファイルが自動で作られています。
$ tree . ├── README.md ├── __init__.py ├── events │ └── event.json ├── hello_world │ ├── __init__.py │ ├── app.py │ └── requirements.txt ├── template.yaml └── tests ├── __init__.py ├── integration │ ├── __init__.py │ └── test_api_gateway.py ├── requirements.txt └── unit ├── __init__.py └── test_handler.py 5 directories, 13 files
hello_world/app.py に Lambda のコードが入っています。
requirements.txt には、依存ライブラリが入っており、sam build すると解決できます。
template.yaml が AWS CloudFormation の構文を拡張した SAM 構文のテンプレートで、これを元にリソースを構築するようになります。以下のテンプレートで、Lambda と API Gateway が作成されます。
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > sam-app Sample SAM Template for sam-app # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 3 Resources: HelloWorldFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: hello_world/ Handler: app.lambda_handler Runtime: python3.8 Events: HelloWorld: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /hello Method: get Outputs: # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function # Find out more about other implicit resources you can reference within SAM # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api HelloWorldApi: Description: "API Gateway endpoint URL for Prod stage for Hello World function" Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/" HelloWorldFunction: Description: "Hello World Lambda Function ARN" Value: !GetAtt HelloWorldFunction.Arn HelloWorldFunctionIamRole: Description: "Implicit IAM Role created for Hello World function" Value: !GetAtt HelloWorldFunctionRole.Arn
アプリケーションを構築する
sam build コマンドは、アプリケーションが持つあらゆる依存関係を .aws-sam/build 下に構築します。
今回はランタイムをPythonにしているので、requirements.txt を解決してくれます。
$ sam build Building codeuri: /mnt/c/vscode/sam-app/hello_world runtime: python3.8 metadata: {} functions: ['HelloWorldFunction'] Running PythonPipBuilder:ResolveDependencies Running PythonPipBuilder:CopySource Build Succeeded Built Artifacts : .aws-sam/build Built Template : .aws-sam/build/template.yaml Commands you can use next ========================= [*] Invoke Function: sam local invoke [*] Deploy: sam deploy --guided
.aws-sam には以下のファイルが作成されました。
$ tree .aws-sam .aws-sam ├── build │ ├── HelloWorldFunction │ │ ├── __init__.py │ │ ├── app.py │ │ ├── certifi │ │ │ ├── __init__.py │ │ │ ├── __main__.py │ │ │ ├── cacert.pem ~略~ │ └── template.yaml └── build.toml
アプリケーションを AWS クラウドにデプロイする
sam deploy コマンドでデプロイしていきます。初回は、--guided オプションを付けることで、対話式で、デプロイの設定を作りつつ、デプロイする事が出来ます。設定の samconfig.toml ファイルが作られるので、次回以降は、--guided オプションなしで deploy ができます。
$ sam deploy --guided Configuring SAM deploy ====================== Looking for config file [samconfig.toml] : Not found Setting default arguments for 'sam deploy' ========================================= Stack Name [sam-app]: AWS Region [ap-northeast-1]: #Shows you resources changes to be deployed and require a 'Y' to initiate deploy Confirm changes before deploy [y/N]: y #SAM needs permission to be able to create roles to connect to the resources in your template Allow SAM CLI IAM role creation [Y/n]: Y HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y Save arguments to configuration file [Y/n]: y SAM configuration file [samconfig.toml]: SAM configuration environment [default]: Enter MFA code for arn:aws:iam::123456789012:mfa/cm-kimura.risa: Looking for resources needed for deployment: Found! Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-ikc487ot1fs7 A different default S3 bucket can be set in samconfig.toml Saved arguments to config file Running 'sam deploy' for future deployments will use the parameters saved above. The above parameters can be changed by modifying samconfig.toml Learn more about samconfig.toml syntax at https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html Uploading to sam-app/f28f4bb6f24c12a2984f985b9f45998c 452537 / 452537 (100.00%) Deploying with following values =============================== Stack name : sam-app Region : ap-northeast-1 Confirm changeset : True Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-ikc487ot1fs7 Capabilities : ["CAPABILITY_IAM"] Parameter overrides : {} Signing Profiles : {} Initiating deployment ===================== Uploading to sam-app/e59ab6ef4171daa5f13a107fb80d0b4f.template 1089 / 1089 (100.00%) Waiting for changeset to be created.. CloudFormation stack changeset ----------------------------------------------------------------------------------------------------- Operation LogicalResourceId ResourceType Replacement ----------------------------------------------------------------------------------------------------- + Add HelloWorldFunctionHello AWS::Lambda::Permission N/A WorldPermissionProd + Add HelloWorldFunctionRole AWS::IAM::Role N/A + Add HelloWorldFunction AWS::Lambda::Function N/A + Add ServerlessRestApiDeploy AWS::ApiGateway::Deploy N/A ment47fc2d5f9d ment + Add ServerlessRestApiProdSt AWS::ApiGateway::Stage N/A age + Add ServerlessRestApi AWS::ApiGateway::RestAp N/A i ----------------------------------------------------------------------------------------------------- Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:12345678912:changeSet/samcli-deploy1643977195/cc05f8af-2d23-46b1-b97f-16d383d0bfb0 Previewing CloudFormation changeset before deployment ====================================================== Deploy this changeset? [y/N]: y 2022-02-04 21:21:36 - Waiting for stack create/update to complete CloudFormation events from changeset ----------------------------------------------------------------------------------------------------- ResourceStatus ResourceType LogicalResourceId ResourceStatusReason ----------------------------------------------------------------------------------------------------- CREATE_IN_PROGRESS AWS::IAM::Role HelloWorldFunctionRole - CREATE_IN_PROGRESS AWS::IAM::Role HelloWorldFunctionRole Resource creation Initiated CREATE_COMPLETE AWS::IAM::Role HelloWorldFunctionRole - CREATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction - CREATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction Resource creation Initiated CREATE_COMPLETE AWS::Lambda::Function HelloWorldFunction - CREATE_IN_PROGRESS AWS::ApiGateway::RestAp ServerlessRestApi - i CREATE_IN_PROGRESS AWS::ApiGateway::RestAp ServerlessRestApi Resource creation i Initiated CREATE_COMPLETE AWS::ApiGateway::RestAp ServerlessRestApi - i CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHello - WorldPermissionProd CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionHello Resource creation WorldPermissionProd Initiated CREATE_IN_PROGRESS AWS::ApiGateway::Deploy ServerlessRestApiDeploy - ment ment47fc2d5f9d CREATE_IN_PROGRESS AWS::ApiGateway::Deploy ServerlessRestApiDeploy Resource creation ment ment47fc2d5f9d Initiated CREATE_COMPLETE AWS::ApiGateway::Deploy ServerlessRestApiDeploy - ment ment47fc2d5f9d CREATE_IN_PROGRESS AWS::ApiGateway::Stage ServerlessRestApiProdSt - age CREATE_IN_PROGRESS AWS::ApiGateway::Stage ServerlessRestApiProdSt Resource creation age Initiated CREATE_COMPLETE AWS::ApiGateway::Stage ServerlessRestApiProdSt - age CREATE_COMPLETE AWS::Lambda::Permission HelloWorldFunctionHello - WorldPermissionProd CREATE_COMPLETE AWS::CloudFormation::St sam-app - ack ----------------------------------------------------------------------------------------------------- CloudFormation outputs from deployed stack ------------------------------------------------------------------------------------------------------ Outputs ------------------------------------------------------------------------------------------------------ Key HelloWorldFunctionIamRole Description Implicit IAM Role created for Hello World function Value arn:aws:iam::12345678912:role/sam-app-HelloWorldFunctionRole-1PNC0H3VIOYKS Key HelloWorldApi Description API Gateway endpoint URL for Prod stage for Hello World function Value https://l3ega04mq5.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/ Key HelloWorldFunction Description Hello World Lambda Function ARN Value arn:aws:lambda:ap-northeast-1:12345678912:function:sam-app-HelloWorldFunction- MQE7TFgX2GnN ------------------------------------------------------------------------------------------------------ Successfully created/updated stack - sam-app in ap-northeast-1
↑出力の HelloWorldApi の Value が API の URL になるので、試しに叩いてみます。
$curl https://l3ega04mq5.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/ {"message": "hello world"}
正常にデプロイされました。
CloudFormtion スタックが作成されています。
中身はこんな感じです。
上記の通り、作成されたのは CloudFormaiton スタックなので、削除の際は、↑の「削除」から削除するか、以下の CloudFormation のコマンドで削除できます。
aws cloudformation delete-stack --stack-name sam-app
最後に
以上、『AWS 再入門ブログリレー 2022』の 4日目のエントリ『AWS SAM』編でした。
来週月曜日 (2/7) はたかくにさんの 「Terraform Public Modules」の予定です。お楽しみに!!